/**
 * 
 */
package account;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import misc.TextFieldFocusListener;
import database.Database;

/**
 * @author Kevin Hanson
 * 
 */
public class AccountPanel extends JPanel implements ActionListener {
	private static Connection conn = null;
	private static Statement stat = null;
	private ResultSet rs = null;
	final static String newline = "\n";
	private AccountTableModel accountTableModel = null;
	private JTable table = null;
	private AccountRecordDialog accountRecordPane = null;
	private SearchDialog searchFrame = null;

	/**
	 * 
	 */
	public AccountPanel() {
		if (!init())
			System.exit(-1);
	}

	public boolean init() {
		try { // Initialize database
			conn = Database.getConnection();
			stat = conn.createStatement();
		} catch (Exception ex) {
			ex.printStackTrace();
			return false;
		}

		createGUI();

		try {
			accountRecordPane = new AccountRecordDialog(new JFrame(), "New account record");
		} catch (HeadlessException e) {
		}

		return true;
	}

	private void createGUI() {
		setLayout(new BorderLayout());

		// Center pane
		JPanel jp0 = new JPanel(new GridLayout(2, 1));

		try {
			accountTableModel = new AccountTableModel(Database.getConnection(), "account");
		} catch (SQLException ex) {
			System.out.print(ex.getMessage());
			ex.printStackTrace();
		}
		table = new JTable(accountTableModel) {
			public boolean isCellEditable(int rowIndex, int vColIndex) {
				return true;
			}
		};
		table.setDragEnabled(false);
		table.setFont(new Font("sansserif", Font.PLAIN, 14));
		// hide column 0 from table model
		table.getColumnModel().removeColumn(table.getColumn("id"));
		table.setCellSelectionEnabled(false);
		table.setRowSelectionAllowed(true);
		table.setColumnSelectionAllowed(false);
		table.getColumn("name").setMaxWidth(80);
		table.getColumn("name").setMinWidth(80);
		table.getColumn("uid").setMaxWidth(200);
		table.getColumn("uid").setMinWidth(200);
		table.getColumn("passwd").setMaxWidth(80);
		table.getColumn("passwd").setMinWidth(80);
		table.getColumn("site").setMaxWidth(200);
		table.getColumn("site").setMinWidth(200);
		table.getColumn("comment").setMaxWidth(200);
		table.getColumn("comment").setMinWidth(100);
		table.setAutoCreateRowSorter(true);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
//		table.getModel().addTableModelListener(new TableModelListener() {
//			public void tableChanged(TableModelEvent e) {
//				System.out.println(e);
//			}
//		});
		ListSelectionModel cellSelectionModel = table.getSelectionModel();
		cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		JScrollPane jsp0 = new JScrollPane(table);
		jsp0.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		jsp0.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		jsp0.setPreferredSize(new Dimension(300, 900));

		jp0.add(jsp0);
		jp0.add(new JPanel());
		jp0.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Account"),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		// East pane
		JPanel jp2 = new JPanel();
		jp2.setLayout(new BoxLayout(jp2, BoxLayout.Y_AXIS));
		jp2.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Action"),
				BorderFactory.createEmptyBorder(5, 5, 5, 5)));

		JTextField jtf = new JTextField("#input string");
		jtf.setFont(new Font(null, Font.ITALIC, 12));
		jtf.setPreferredSize(new Dimension(20, 20));
		jtf.setMaximumSize(new Dimension(200, 25));
		jtf.addFocusListener(new TextFieldFocusListener(jtf));

		JButton jb0 = new JButton("New");
		jb0.setMinimumSize(new Dimension(100, 20));
		jb0.setMaximumSize(new Dimension(100, 20));
		jb0.addActionListener(this);

		JButton jb1 = new JButton("Delete");
		jb1.setMinimumSize(new Dimension(100, 20));
		jb1.setMaximumSize(new Dimension(100, 20));
		jb1.addActionListener(this);

		JButton jb2 = new JButton("Search");
		jb2.setMinimumSize(new Dimension(100, 20));
		jb2.setMaximumSize(new Dimension(100, 20));

		jp2.add(jtf);
		jp2.add(Box.createHorizontalGlue());
		jp2.add(jb2);
		jp2.add(Box.createHorizontalGlue());
		jp2.add(jb0);
		jp2.add(Box.createHorizontalGlue());
		jp2.add(jb1);

		// Root pane
		add(jp0, BorderLayout.CENTER);
		add(jp2, BorderLayout.EAST);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent arg0) {
		String str = arg0.getActionCommand();
		// System.out.print(str + newline);
		if (str == "New") {
			/**
			 * routine blocking here on a modal dialog shown, it's not a good
			 * idea in event handler which blocks the GUI process
			 */
			if (accountRecordPane.isVisible())
				accountRecordPane.setVisible(false);
			else
				accountRecordPane.setVisible(true);
			accountTableModel.updateTable();
		} else if (str == "Delete") {
			deleteRecord();
		} else if (str == "New record") {
			accountRecordPane.setVisible(false);
			addRecord();
		}
	}

	public boolean deleteRecord() {
		int row = 0;
		try {
			PreparedStatement prep = conn.prepareStatement("DELETE FROM account WHERE id = ?;");
			// haven't taken the case of hidden rows into consideration
			row = table.getSelectionModel().getMinSelectionIndex();
			// System.out.println(row);
			// System.out.println(table.getModel().getValueAt(row,
			// 0).toString());
			prep.setString(1, table.getModel().getValueAt(row, 0).toString());
			prep.execute();
			if (!conn.getAutoCommit())
				conn.commit();
		} catch (SQLException ex) {
			System.out.print(ex.getMessage());
			ex.printStackTrace();
		}
		accountTableModel.updateTable();
		// refresh table, both working
		// table.repaint();
		// accountTableModel.fireTableRowsDeleted(row, row);

		return true;
	}

	private boolean addRecord() {
		try {
			PreparedStatement prep = conn.prepareStatement("INSERT INTO account VALUES (null, ?, ?, ?, ?, ?);");
			// haven't taken the case of hidden rows into consideration
			prep.setString(1, accountRecordPane.getAccountInfo("name"));
			prep.setString(2, accountRecordPane.getAccountInfo("uid"));
			prep.setString(3, accountRecordPane.getAccountInfo("passwd"));
			prep.setString(4, accountRecordPane.getAccountInfo("site"));
			prep.setString(5, accountRecordPane.getAccountInfo("comment"));
			prep.execute();
			if (!conn.getAutoCommit())
				conn.commit();
		} catch (SQLException ex) {
			System.out.print(ex.getMessage());
			ex.printStackTrace();
		}
		accountTableModel.updateTable();

		return true;
	}
}
